package com.app.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.app.bean.vo.LoginBean;
import com.app.bean.vo.LoginResult;
import com.app.common.Const;
import com.app.common.enums.DataStatusEnum;
import com.app.dao.UserRepository;
import com.app.entity.User;
import com.app.exceptions.BusinessException;
import com.app.service.IUserService;
import com.app.utils.BloomFilterUtil;
import com.app.utils.CacheUtil;
import com.app.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;

import static com.app.common.RabbitConst.EXCHANGE_NAME;
import static com.app.common.RabbitConst.ROUTING_KEY;

/**
 * @autor xiaoyu.fang
 * @date 2019/10/12 11:16
 */
@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    @Value("${wx.app.appid}")
    private String appid;

    @Value("${wx.app.secret}")
    private String secret;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private CacheUtil cacheUtil;

    @Autowired
    private BloomFilterUtil bloomFilterUtil;

    @Override
    public LoginResult findByCode(LoginBean loginBean) {
        String jsonId = getOpenID(loginBean.getCode());
        JSONObject jsonObject = JSONObject.parseObject(jsonId);
        // 从json字符串获取openid
        String openid = jsonObject.getString("openid");
        if (openid == null) {
            throw new BusinessException("小程序登录失败");
        }
        User user = userRepository.findByOpenId(openid);
        if (user == null) {
            user = userRepository.insert(buildUser(loginBean, openid));
        } else {
            if (!user.getDataStatus().equals(DataStatusEnum.VALID.KEY)) {
                throw new BusinessException("用户账号异常");
            }
        }
        String tokenKey = UUIDUtil.getID();
        String rtJson = JSON.toJSONString(user);
        cacheUtil.set(tokenKey, rtJson, 7 * 24 * 60 * 60);
        // 刷新token，不同的端保留不同的token
        String refleshTokenKey = String.format("%s:%s:%s", Const.REFLESH_TOKEN_PREFIX, user.getId(), loginBean.getTerminalId());
        if (cacheUtil.hasKey(refleshTokenKey)) {
            String last_key = cacheUtil.get(refleshTokenKey).toString();
            cacheUtil.del(last_key);
        }
        cacheUtil.set(refleshTokenKey, tokenKey);
        LoginResult result = new LoginResult();
        result.setOpenId(openid);
        result.setToken(tokenKey);
        result.setNickName(user.getNickName());
        result.setAvatarUrl(user.getAvatarUrl());
        return result;
    }

    @Override
    public User findById(ObjectId id) {
        return userRepository.findByIdAndDataStatus(id, DataStatusEnum.VALID.KEY);
    }

    @Override
    public void insert(User user) {
        user.setCreateAt(new Date());
        user.setDataStatus(DataStatusEnum.VALID.KEY);
        userRepository.insert(user);
    }

    @Override
    public void addBusiness(User user) {
        String userJson = JSONObject.toJSONString(user);
        rabbitTemplate.convertAndSend(EXCHANGE_NAME, ROUTING_KEY, userJson);
    }

    @Override
    public void testBloomFilter(String value) {
        log.info("是否存在？ >>>>>>>>>> {}", bloomFilterUtil.contains(value));
        if (!bloomFilterUtil.contains(value)) {
            bloomFilterUtil.add(value);
            log.info("<<<<<<<<<< 已添加 >>>>>>>>>");
            log.info("是否存在？ >>>>>>>>>> {}", bloomFilterUtil.contains(value));
        }
    }

    private String getOpenID(String code) {
        BufferedReader in = null;
        String wxUrl = StrUtil.format(Const.WX_URL, appid, secret, code);
        try {
            URL weChatUrl = new URL(wxUrl);
            // 打开和URL之间的连接
            URLConnection connection = weChatUrl.openConnection();
            // 设置通用的请求属性
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            // 建立实际的连接
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuffer stringBuffer = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                stringBuffer.append(line);
            }
            return stringBuffer.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private User buildUser(LoginBean loginBean, String openId) {
        User user = new User();
        user.setNickName(loginBean.getNickName());
        user.setAvatarUrl(loginBean.getAvatarUrl());
        user.setPhone(loginBean.getPhone());
        user.setOpenId(openId);
        user.setCreateAt(new Date());
        user.setDataStatus(DataStatusEnum.VALID.KEY);
        return user;
    }
}
